import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
// import { logger } from './common/middleware/logger.middleware';
import { ValidationPipe, VersioningType } from '@nestjs/common';
import cookieParser from 'cookie-parser';
// import * as compression from 'compression';
import session from 'express-session';
// import { redisStore } from 'cache-manager-redis-yet';
// import RedisStore from 'connect-redis';
// import { createClient } from 'redis';
import configuration from './config/configuration';
import helmet from 'helmet';
// import rateLimit from 'express-rate-limit';
import { WsAdapter } from '@nestjs/platform-ws';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
// import { ConfigService } from '@nestjs/config';
import { useContainer } from 'class-validator';
import {
  PagingDto,
  PagingResponse,
  PagingResponseDto,
  ResponseDto,
} from './common/dto/paging.dto';
import { json, urlencoded } from 'express';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';

// import { ValidationPipe } from './common/pipes/validation.pipe';
// import { HttpExceptionFilter } from './common/filters/http-exception.filter';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
    logger: ['log', 'error', 'warn'],
    cors: true,
  });

  // 通过use全局注册函数式中间件
  // app.use(logger);

  // 注册全局过滤器
  // app.useGlobalFilters(new HttpExceptionFilter());
  // const configService = app.get(ConfigService)
  // class-validator 的 DTO 类中注入 nest 容器的依赖 (用于自定义验证器)
  useContainer(app.select(AppModule), { fallbackOnErrors: true });

  app.use(helmet());
  // 请求速率限制
  app.use(
    // rateLimit({
    //   windowMs: 0.5 * 60 * 1000, // 0.5分钟
    //   max: 600, // 将每个IP限制为每个窗口600个请求
    // }),
    json({ limit: '10mb' }),
    // 如果你的应用还处理表单数据（即 'application/x-www-form-urlencoded'），你可能还需要设置
    urlencoded({ limit: '10mb', extended: true }),
  );

  // 设置信任代理
  app.set('trust proxy', 'loopback');
  // 'loopback'是一个特殊值，表示NestJS信任来自回环地址（127.0.0.1）的代理。如果你的代理服务器的IP不在回环地址之外，你需要替换为实际代理服务器的IP地址或使用特殊值true来信任所有代理。

  // 注册全局校验管道
  app.useGlobalPipes(
    new ValidationPipe({
      transform: true,
      // disableErrorMessages: true, // 不会将错误消息返回给最终用户
    }),
  );

  // 启用header版本管理
  app.enableVersioning({
    type: VersioningType.MEDIA_TYPE,
    key: 'v=',
  });

  // 注册全局守卫
  // app.useGlobalGuards(new JwtAuthGuard());

  // 配置cookie全局中间件
  app.use(cookieParser());

  // // 压缩中间件 (使用nginx则不应该使用压缩中间件)
  // app.use(compression);
  // console.log(configuration().redis);
  // 配置session中间件
  // const redisClient = createClient({
  //   socket: {
  //     host: configuration().redis.host,
  //     port: configuration().redis.port,
  //   },
  //   password: configuration().redis.password,
  //   database: configuration().redis.db,
  // });
  // redisClient.connect().catch(console.error);
  app.use(
    session({
      // store: new RedisStore({
      //   client: redisClient,
      //   ttl: configuration().redis.ttl,
      // }),
      secret: 'asfs4471jm12445jhgfdsdsj4j59sbw142o204i8129ehf6ysd',
      resave: false,
      saveUninitialized: false,
      // cookie: {
      //   maxAge: 1000 * 60 * 60 * 24 * 7,
      // },
    }),
  );
  app.useWebSocketAdapter(new WsAdapter(app));
  // 设置全局前缀
  app.setGlobalPrefix(configuration().apiPrefix);

  const config = new DocumentBuilder()
    .setTitle(`${configuration().swagger.title} API`)
    .setDescription('Word AI API description')
    .setVersion('1.0')
    .addBearerAuth({
      type: 'http',
      in: 'header',
      name: 'Authorization',
      scheme: 'bearer',
    })

    .addTag('root')
    // .addServer(`${configuration().apiPrefix}`)
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup(`docs`, app, document, {
    jsonDocumentUrl: 'docs/json',
    swaggerOptions: {
      validatorUrl: null,
      deepScanRoutes: true,
      ignoreGlobalPrefix: true,
      extraModels: [PagingResponse, ResponseDto, PagingDto, PagingResponseDto],
    },
  });

  app.useStaticAssets(join(__dirname, '..', 'public'));

  app.enableCors({
    origin: true,
    methods: 'GET,PUT,POST',
    allowedHeaders: 'Content-Type,Authorization,Referrer Policy',
    exposedHeaders: 'Content-Range,X-Content-Range',
    credentials: true,
    maxAge: 3600,
  });
  const server = await app.listen(configuration().port);
  server.setTimeout(1800000); // 600,000=> 10Min, 1200,000=>20Min, 1800,000=>30Min
  console.log(`started ${configuration().port}`);
}
bootstrap();
